////////////////////////////////////////////////////////////////////////////////
//
// #   # #   # ####  #     #   #  #### ##### #   # #   #  ###  #   #  ###   ####
// ## ##  # #  #   # #     #   # #       #   ##  # ## ## #   # ##  # #   # #
// # # #   #   ####  #     #   # # ###   #   # # # # # # ##### # # # ##### # ###
// #   #  # #  #     #     #   # #   #   #   #  ## #   # #   # #  ## #   # #   #
// #   # #   # #     #####  ###   #### ##### #   # #   # #   # #   # #   #  ####
//
////////////////////////////////////////////////////////////////////////////////
//
// File:	MxPluginManager.h
// Class:	MxPluginManager
//
////////////////////////////////////////////////////////////////////////////////
//
// Declares the class MxPluginManager that can be used to manage MxPlugin-based
// libraries
//
////////////////////////////////////////////////////////////////////////////////
//
// Author:		$Author$
// Revision:	$Revision$
// Date:		$Date$
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright:	(C) 2012 by Maximodex Limited
// License:		This software is distributed under a New BSD License
//
////////////////////////////////////////////////////////////////////////////////

#ifndef __mxpluginmanager_h__
# define __mxpluginmanager_h__

# ifndef MXPLUGINMANAGER_API
#  ifdef WIN32
#   ifdef MXPLUGINMANAGER_EXPORTS
#    define MXPLUGINMANAGER_API __declspec(dllexport)
#   else
#    define MXPLUGINMANAGER_API __declspec(dllimport)
#   endif
#  else
#   define MXPLUGINMANAGER_API
#  endif
# endif

# ifndef WIN32
#  ifndef DWORD
#   define DWORD int32_t
#  endif
#  ifndef HINSTANCE
#   define HINSTANCE void *
#  endif
#  ifndef HANDLE
#   define HANDLE void *
#  endif
#  ifndef INVALID_HANDLE_VALUE
#   define INVALID_HANDLE_VALUE NULL
#  endif
# endif

# include <cstdint>
# include <vector>

# include "MxPluginLib.h"
# include "gLibDetails.h"

# ifndef WIN32
#  define MXPLUGIN_FILE_NOT_FOUND ENOENT
#  define MXPLUGIN_NO_MORE_FILES  ENOENT
# else
#  define MXPLUGIN_FILE_NOT_FOUND ERROR_FILE_NOT_FOUND
#  define MXPLUGIN_NO_MORE_FILES  ERROR_NO_MORE_FILES
# endif

class MXPLUGINMANAGER_API MxPluginManager
{
	public:
		static const char * const FnNameCreateClassInstance;
		static const char * const ErrorCodeList;
		static const wchar_t * const wErrorCodeList;

		static const DWORD NoError = 0;
		static const DWORD UnknownError = 30000;
		static const DWORD CreateMxPluginLibError = 30001;
		static const DWORD AddMxPluginLibError = 30002;
		static const DWORD ExceptionError = 30003;
		static const DWORD InvalidParams = 3004;
		static const DWORD NoMxPluginsForIID = 30005;
		static const DWORD InvalidRegKey = 30006;

		MxPluginManager(void);
		~MxPluginManager(void);

		void ClearAllMxPlugins();
		int GetPluginCount();
		MxPluginLib *GetPlugin(int index);
		MxPluginLib *GetPlugin(const char *LibIid);
		DWORD RefreshPluginsInSubFolders(const wchar_t *PluginRootFolder,
			const char *IID);
		DWORD RefreshPluginsInFolder(const wchar_t *PluginFolder,
			const char *IID);

		const char *GetLibName(void);
		const char *GetLibDescription(void);
		const char *GetLibVersion(void);
		const char *GetLibOwnerName(void);
		const char *GetLibCopyrightNotice(void);
		const char *GetLibInternalName(void);
		const char *GetLibSupportSite(void);
		const char *GetLibLicenseName(void);
		const char *GetLibLicenseURL(void);
		const char *GetLibPathFilename(void);

	private:
		DWORD RefreshPlugins(const wchar_t *PluginFolder, const char *IID);
		bool AddMxPlugin(MxPluginLib *lib);
		bool IsExisting(MxPluginLib *lib);
		void ClearAllSelections();
		bool DeleteNextUnselected();

		DWORD GetFirstPluginFolderItem(std::wstring *firstFolderResult,
			const wchar_t *PluginRootFolder, void *hFindFolder,
			bool FindFolder);
		DWORD GetNextPluginFolderItem(std::wstring *nextFolderResult,
			const wchar_t *PluginRootFolder, void *hFindFolder,
			bool FindFolder);
		bool IsValidLib(const wchar_t *filename);

	private:
		std::vector<MxPluginLib *> _Libs;
};

#endif // __mxpluginmanager_h__
